package com.budwk.app.sqfwV2.generator.dayingRoadExcel;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.sqfw.constants.DictConstants;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfwDoc.bo.SqfwExcelForSummaryBO;
import com.budwk.app.sqfwDoc.bo.SqfwExcelJudgeRes;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.BaseTemplateExcelGenerator;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.SqfwExcelCreateCommonBO;
import com.budwk.app.sqfwV2.component.DayingRoadPdfComponent;
import com.budwk.app.sqfwV2.dto.dto.FireSafetyOnDayingRoadPdfDTO;
import com.budwk.app.sqfwV2.dto.dto.centuryCity.SafeCheckTaskParamDataDTO;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.AccommodatePeopleVo;
import com.budwk.app.sqfwV2.dto.image.FireSafetyOnDayingRoadExcelImageConfigBO;
import com.budwk.app.sqfwV2.enums.DayingRoadFileServiceEnum;
import com.budwk.app.sqfwV2.enums.dayingRoad.DayingRoadProblemEnum;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.util.StrUtil;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.app.util.poiUtils.excelPictureConfigBO.ExcelFileCreateParamBO;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;

import java.util.*;

/**
 * 消防安全巡查检查台账
 */

@Slf4j
public class InspectionOnPatrolGenerator extends BaseTemplateExcelGenerator implements DayingRoadExcelGenerator {

    @Override
    protected String getTemplateName() {
        return DayingRoadFileServiceEnum.DAYING_ROAD_EXCEL_LEDGER.getFilePath();
    }

    /**
    * 可以参照 {@link com.budwk.app.sqfw.enums.DownLoadFileNameEnum}
    *
    * @return 文件名名称
    */
    @Override
    public String getDownloadFileName() {
        //TODO 在这里返回你生成的文件名名称，注意注意注意不用带上后缀
        return DayingRoadPdfComponent.getDictName(DayingRoadFileServiceEnum.DAYING_ROAD_EXCEL_LEDGER.getCode(), null);
    }

    /**
     * 用户自定义excel基础参数，比如表头这样的公用数据
     * @param excelParam 已经填充的基础数据据
     * @param excelCreateParam excel生成提供的原料
     */
    @Override
    protected void customerPopularSheetBaseParam(Map<String, Object> excelParam, SqfwExcelCreateCommonBO excelCreateParam) {
        excelParam.put("unitName", excelCreateParam.getBaseExcelParamDTO().getUnitName());
    }

    @Override
    protected void customerPopularSheetDataParam(List<Map<String, Object>> listMap, SqfwExcelCreateCommonBO excelCreateParam) {
        log.info("InspectionOnPatrolGenerator build start");
        List<Sqfw_formSummary_new> summaryList = DayingRoadPdfComponent.getSummaryList(listMap, excelCreateParam);
        // 构建参数对象
        buildSheetDataParam(summaryList, listMap);
        log.info("InspectionOnPatrolGenerator end");
    }

    private void buildSheetDataParam(List<Sqfw_formSummary_new> formSummaryNews, List<Map<String, Object>> listMap) {
        int num = 1;
        for (Sqfw_formSummary_new formSummaryNew : formSummaryNews) {
            // 1 获取问题集
            FireSafetyOnDayingRoadPdfDTO roadPdfDTO = JSONObject.parseObject(formSummaryNew.getParamData(), FireSafetyOnDayingRoadPdfDTO.class);
            if (!isGenerateExcel(roadPdfDTO)) {
                continue;
            }
            // 2 构建map对象
            Map<String, Object> map = buildMap(formSummaryNew, roadPdfDTO, roadPdfDTO.getInspectionOnPatrolProblem());
            map.put("num", num ++);
            listMap.add(map);
        }
    }

    /**
     * ●生成表格注意事项：
     * ○以下情况生成表格
     * ○如果a33不等于否，则【三合一】
     * ○如果a36等于【有安全出口，但设置卷帘门，铁栅栏等】，则【直接取当前值】
     * ○如果a37等于【有逃生出口，但设置防盗窗等】，则【直接取当前值】
     * ○如果a44等于0，则【没有灭火器】
     * ○如果a46不等于合格，则【直接取当前值】
     * ○如果a47不等于无，则【直接取当前值】
     * ○如果a48不等于否，则【使用明火、高温加热、取暖设备】
     * ○如果a49不等于否，则【存放有易燃易爆危险品】
     * ○如果a50等于是，则【黑酒精】
     * ○如果a7等于使用醇基燃料，则【醇基燃料】。
     *  增加其他隐患
     */
    public boolean isGenerateExcel(FireSafetyOnDayingRoadPdfDTO roadPdfDTO) {
        // 判断a5是否为重点场所 选择重点场所 不生成表格
        if (DayingRoadPdfComponent.isKeyLocations(roadPdfDTO)) {
            return false;
        }
        String inspectionOnPatrolProblem = getProblem(roadPdfDTO);
        roadPdfDTO.setInspectionOnPatrolProblem(inspectionOnPatrolProblem);
        return StringUtils.isNotEmpty(inspectionOnPatrolProblem);
    }

    private Map<String, Object> buildMap(Sqfw_formSummary_new formSummaryNew, FireSafetyOnDayingRoadPdfDTO roadPdfDTO, String problem) {
        Map<String, Object> map = new HashMap<>();
        map.put("unitName", StrUtil.replaceNullStr(formSummaryNew.getUnitName()));
        map.put("placeName", StrUtil.replaceNullStr(roadPdfDTO.getPlaceName()));
        map.put("buildingTypeName", DayingRoadPdfComponent.getDictName(roadPdfDTO.getBuildingType(), roadPdfDTO.getBuildingTypeName()));
        map.put("address", StrUtil.replaceNullStr(roadPdfDTO.getAddress()));
        map.put("operator", StrUtil.replaceNullStr(roadPdfDTO.getOperator()));
        map.put("problem", problem);
        map.put("operatorTelephone", StrUtil.replaceNullStr(roadPdfDTO.getOperatorTelephone()));
        map.put("rectifyingDangersMeasures", StrUtil.replaceNullStr(roadPdfDTO.getRectifyingDangersMeasures()));
        map.put("inspectionDate", LocalDateTimeUtil.format(roadPdfDTO.getInspectionDate(), DatePattern.NORM_DATETIME_PATTERN));
        map.put("checkedUnitLeader", "");
        if (StringUtils.isNotEmpty(roadPdfDTO.getCheckedUnitLeader())) {
            map.put("checkedUnitLeader", CommonFormOfficeUtils.addPictureToByteList(roadPdfDTO.getCheckedUnitLeader(), 1));
        }
        return map;
    }

    private String getAccommodatePeopleVo(AccommodatePeopleVo accommodatePeople) {
        if (accommodatePeople != null) {
            // 1 是否住人
            if (DayingRoadPdfComponent.isAccommodatePeople(accommodatePeople)) {
                return "三合一";
            }
        }
        return null;
    }

    private String getProblem(FireSafetyOnDayingRoadPdfDTO roadPdfDTO) {
        SysDictService dictService = NutzIocUtils.getBean(SysDictService.class);
        List<String> problemStr = new ArrayList<>();
        String accommodatePeopleVo = getAccommodatePeopleVo(roadPdfDTO.getAccommodatePeople());
        if (StringUtils.isNotEmpty(accommodatePeopleVo)) {
            problemStr.add(accommodatePeopleVo);
        }
        // 4 ○如果a44等于0，则【没有灭火器】
        SafeCheckTaskParamDataDTO pfen = roadPdfDTO.getWhetherEquippedFire();
        if (pfen.getKey().equals("false")) problemStr.add("没有灭火器");

        // 5 ○如果a46不等于合格，则【直接取当前值】->电气线路情况
        SafeCheckTaskParamDataDTO p = roadPdfDTO.getElectricalCircuitSituation();
        if (p != null) {
            // 1 合格
            if (!DictConstants.ELECTRICAL_CIRCUIT_QUALIFIED.equals(p.getKey())) {
                Sys_dict sysDict = dictService.fetch(Cnd.where(Sys_dict::getCode, "=", p.getKey()));
                problemStr.add(sysDict.getName());
            }
        }
        // 6 ○如果a47不等于无，则【直接取当前值】->电动自行车使用情况
        SafeCheckTaskParamDataDTO p2 = roadPdfDTO.getElectricBicyclesUse();
        if (p2 != null) {
            Sys_dict sysDict = dictService.fetch(Cnd.where(Sys_dict::getCode, "=", p2.getKey()));
            if (!DictConstants.BICYCLES_NO.equals(p2.getKey())) {
                problemStr.add(sysDict.getName());
            }
        }
        // 7 ○如果a48不等于否，则【使用明火、高温加热、取暖设备】
        SafeCheckTaskParamDataDTO ppd = roadPdfDTO.getFireHighUsageArea();
        if (ppd != null) {
            if (!DictConstants.FLAMES_HIGH_HEAT_NO.equals(ppd.getKey())) {
                problemStr.add("使用明火、高温加热、取暖设备");
            }
        }
        // 8 ○如果a49不等于否，则【存放有易燃易爆危险品】
        SafeCheckTaskParamDataDTO pie = roadPdfDTO.getIsCombustiblEexplosive();
        if (pie != null) {
            if (!String.valueOf(Boolean.FALSE).equals(pie.getKey())) {
                problemStr.add("存放有易燃易爆危险品");
            }
        }
        // ○如果a50等于是，则【黑酒精】
        SafeCheckTaskParamDataDTO isBlackAlcoholUsed = roadPdfDTO.getIsBlackAlcoholUsed();
        if (isBlackAlcoholUsed != null && String.valueOf(true).equals(isBlackAlcoholUsed.getKey())) {
            problemStr.add("黑酒精");
        }
        // ○如果a7等于使用醇基燃料，则【醇基燃料】。
        String fireAndElectricityUsage = roadPdfDTO.getFireAndElectricityUsage();
        if (StringUtils.isNotEmpty(fireAndElectricityUsage) && fireAndElectricityUsage.contains(DictConstants.BOTTLED_GAS_FUELS)) {
            problemStr.add("醇基燃料");
        }
        // 增加其他隐患
        List<SafeCheckTaskParamDataDTO> otherHiddenDangers = roadPdfDTO.getOtherHiddenDangers();
        if (otherHiddenDangers != null && otherHiddenDangers.size() > 0) {
            // 取第一条数据
            SafeCheckTaskParamDataDTO s1 = otherHiddenDangers.get(0);
            SafeCheckTaskParamDataDTO s2 = DayingRoadProblemEnum.initData(DayingRoadProblemEnum.TWELVE);
            if (!s1.getKey().equals(s2.getKey())) {
                // 判断是否是立即整改
                problemStr.add(s1.getRectificationMeasure());
            }
        }
        if (problemStr.size() > 0) {
            return String.join("、", problemStr);
        }
        return StringUtils.EMPTY;
    }

    @Override
    protected void completeExcelFileCreateParam(ExcelFileCreateParamBO excelFileCreateParam) {

    }

    @Override
    protected void customerPopularRowDataMap(Map<String, Object> rowDataMap, SqfwExcelForSummaryBO forSummaryBO) {

    }

    /**
     * 如果在遍历之前就能够判断excel是否生成，那么就在这个方法中进行判断
     * @param excelCreateParam excel生成所需的最为全面的数据
     * @param excelParam excel已经填充的部分数据
     */
    @Override
    protected SqfwExcelJudgeRes judgeDataIntoExcelBeforeErgodic(SqfwExcelCreateCommonBO excelCreateParam, Map<String, Object> excelParam) {
        return DayingRoadPdfComponent.getSqfwExcelJudgeRes(excelCreateParam, new InspectionOnPatrolGenerator());
    }

    /**
     * 如果在遍历之后能够判断excel是否生成，那么就在这个方法中进行判断
     * @param excelParam excel已经填充的部分数据
     */
    @Override
    protected SqfwExcelJudgeRes judgeDataIntoExcelBeforeCreate(Map<String, Object> excelParam) {
        return null;
    }

    @Override
    protected Class<?> getImageConfigBO() {
        return FireSafetyOnDayingRoadExcelImageConfigBO.class;
    }
}
